﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.DAL.DocumentCenter;
using Microsoft.SharePoint;
using MS.InformationManagement.DAL.DTOs;

namespace MS.InformationManagement.BLL.DeliveryMeans
{
    public class DeliveryMeansConfigBLL
    {
        public static bool DeliveryMeanExists(string title, bool isSecureDeliveryMean)
        {
            bool alreadyExists = false;

            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                alreadyExists = ctx.MediosDeEnvio.Count(dm => dm.Title.Equals(title) && dm.EsCorreoCertificado.Equals(isSecureDeliveryMean)) > 0;
            }

            return alreadyExists;
        }

        public static void AddDeliveryMean(string title, bool isSecureDeliveryMean, System.Collections.Generic.List<DAL.DTOs.DeliveryMeanConfigDTO> deliveryMeanConfigItems)
        {
            System.Collections.Generic.List<DAL.DocumentCenter.ConfiguracionDeCostosDeMedioDeEnvio> entities = new List<ConfiguracionDeCostosDeMedioDeEnvio>();
            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                MedioDeEnvio deliveryMean = new MedioDeEnvio { Title = title, EsCorreoCertificado = isSecureDeliveryMean };

                deliveryMeanConfigItems.ForEach(delegate(DAL.DTOs.DeliveryMeanConfigDTO currentItem)
                {
                    entities.Add(new ConfiguracionDeCostosDeMedioDeEnvio
                    {
                        CostoLocal = currentItem.LocalCost,
                        CostoNacional = currentItem.NationalCost,
                        LímiteInferior = currentItem.LowerWeightLimit,
                        LímiteSuperior = currentItem.UpperWeightLimit,
                        MedioEnvioCostos = deliveryMean,
                        Title = string.Format("Configuración de fletes para {0}", title)
                    });
                });
                
                ctx.MediosDeEnvio.InsertOnSubmit(deliveryMean);
                ctx.ConfiguracionesDeCostosDeMediosDeEnvio.InsertAllOnSubmit(entities);

                ctx.SubmitChanges();

            }
        }

        public static IEnumerable<ConfiguracionDeCostosDeMedioDeEnvio> GetDeliveryMeans(int pageIndex, int pageSize, out int totalRecords)
        {
            IEnumerable<ConfiguracionDeCostosDeMedioDeEnvio> foundDeliveryMeans = null;
            int startingIndex = pageIndex * pageSize;

            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                foundDeliveryMeans = ctx.ConfiguracionesDeCostosDeMediosDeEnvio.Skip(startingIndex).Take(pageSize);
                totalRecords = ctx.ConfiguracionesDeCostosDeMediosDeEnvio.Count();
            }

            return foundDeliveryMeans;
        }

        public static void UpdateDeliveryMean(int deliveryMeanId, string title, System.Collections.Generic.List<DAL.DTOs.DeliveryMeanConfigDTO> deliveryMeanConfigItems)
        {

            MedioDeEnvio deliveryMean = null;

            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                deliveryMean = ctx.MediosDeEnvio.SingleOrDefault(dm => dm.Id.Equals(deliveryMeanId));
                System.Collections.Generic.List<DAL.DocumentCenter.ConfiguracionDeCostosDeMedioDeEnvio> newElements = new List<DAL.DocumentCenter.ConfiguracionDeCostosDeMedioDeEnvio>();

                if (deliveryMean == default(MedioDeEnvio))
                {
                    throw new NullReferenceException(string.Format("No se encuentra el medio de envío identificado con el Id {0}", deliveryMeanId));
                }

                deliveryMean.Title = title;

                deliveryMeanConfigItems.ForEach(delegate(DAL.DTOs.DeliveryMeanConfigDTO currentItem)
                {
                    ConfiguracionDeCostosDeMedioDeEnvio currentEntity = ctx.ConfiguracionesDeCostosDeMediosDeEnvio.SingleOrDefault(config => config.Id.Equals(currentItem.Id));
                    if (currentEntity == default(ConfiguracionDeCostosDeMedioDeEnvio))
                    {
                        if (currentItem.Id == 0)
                        {
                            currentEntity = new ConfiguracionDeCostosDeMedioDeEnvio();
                            currentEntity.MedioEnvioCostos = deliveryMean;
                            newElements.Add(currentEntity);
                        }
                        else
                        {
                            throw new NullReferenceException(string.Format("No se encuentra la configuración para el medio de envio, identificada con el Id {0}", currentItem.Id));
                        }
                    }

                    currentEntity.CostoLocal = currentItem.LocalCost;
                    currentEntity.CostoNacional = currentItem.NationalCost;
                    currentEntity.LímiteInferior = currentItem.LowerWeightLimit;
                    currentEntity.LímiteSuperior = currentItem.UpperWeightLimit;
                    currentEntity.Title = string.Format("Configuración de fletes para {0}", title);

                });

                if (newElements.Count > 0) { ctx.ConfiguracionesDeCostosDeMediosDeEnvio.InsertAllOnSubmit(newElements); }
                ctx.SubmitChanges();
            }
        }

        public static IEnumerable<ConfiguracionDeCostosDeMedioDeEnvio> GetDeliveryMean(int id)
        {
            IEnumerable<ConfiguracionDeCostosDeMedioDeEnvio> foundEntities = null;

            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                foundEntities = ctx.ConfiguracionesDeCostosDeMediosDeEnvio.Where(config => config.MedioEnvioCostos.Id.Equals(id));
            }

            return foundEntities;
        }

        public static ConfiguracionDeCostosDeMedioDeEnvioDTO GetDeliveryMeanConfig(int deliveryMeanId, double mailWeight)
        {
            ConfiguracionDeCostosDeMedioDeEnvioDTO entity = null;

            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {

                ConfiguracionDeCostosDeMedioDeEnvio foundConfig = ctx.ConfiguracionesDeCostosDeMediosDeEnvio.Where(
                        config => config.MedioEnvioCostos.Id.Equals(deliveryMeanId) 
                            && config.LímiteInferior <= mailWeight && config.LímiteSuperior >= mailWeight
                    ).ToList().SingleOrDefault();
                if (foundConfig != default(ConfiguracionDeCostosDeMedioDeEnvio))
                {
                    entity = new ConfiguracionDeCostosDeMedioDeEnvioDTO
                    {
                        DeliveryMeanName = foundConfig.MedioEnvioCostos.Title,
                        LocalDeliveryCost = foundConfig.CostoLocal.Value,
                        NationalDeliveryCost = foundConfig.CostoNacional.Value,
                        UpperWeightLimit = foundConfig.LímiteSuperior.Value,
                        LowerWeightLimit = foundConfig.LímiteInferior.Value,
                        Id = foundConfig.Id.Value
                    };
                }
            }

            return entity;
        }

        public static bool DeliveryMeanExistsForUpdate(int id, string title, bool isSecureDeliveryMean)
        {
            bool alreadyExists = false;

            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                alreadyExists = ctx.MediosDeEnvio.Count(dm => !dm.Id.Equals(id) && (dm.Title.Equals(title) && dm.EsCorreoCertificado.Equals(isSecureDeliveryMean))) > 0;
            }

            return alreadyExists;
        }

        public static void DeleteDeliveryMean(int id)
        {
            ConfiguracionDeCostosDeMedioDeEnvio foundEntity = null;
            MedioDeEnvio foundDeliveryMean = null;
            int foundDeliveryMeanId = 0;
            using (DCDocumentCenterDataContext ctx = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {

                foundEntity = ctx.ConfiguracionesDeCostosDeMediosDeEnvio.SingleOrDefault(config => config.Id.Equals(id));

                if (foundEntity == default(ConfiguracionDeCostosDeMedioDeEnvio))
                    throw new NullReferenceException(string.Format("No se encuentra la configuración para el medio de envio, identificada con el Id {0}", id));

                foundDeliveryMeanId = foundEntity.MedioEnvioCostos.Id.Value;
                ctx.ConfiguracionesDeCostosDeMediosDeEnvio.RecycleOnSubmit(foundEntity);
                ctx.SubmitChanges();

                foundDeliveryMean = ctx.MediosDeEnvio.SingleOrDefault(dm => dm.Id.Equals(foundDeliveryMeanId));

                if (foundDeliveryMean == default(MedioDeEnvio))
                    throw new NullReferenceException(string.Format("No se encuentra el medio de envío identificado con el Id {0}", foundEntity.MedioEnvioCostos.Id));
                

                if (foundDeliveryMean.ConfiguracionDeCostosDeMedioDeEnvio.Count == 0)
                {
                    ctx.MediosDeEnvio.RecycleOnSubmit(foundDeliveryMean);
                    ctx.SubmitChanges();
                }
            }
        }

    }
}
